package cn.csc.module.pay.mq.listener;

import cn.csc.framework.common.util.json.JsonUtils;
import cn.csc.module.pay.dal.dataobject.order.PayOrderDO;
import cn.csc.module.pay.dal.mysql.order.PayOrderMapper;
import cn.csc.module.pay.message.PayOrderNotifyMessage;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * 支付订单支付成功消息事务监听器
 * rocketmq事务消息：https://rocketmq.apache.org/zh/docs/featureBehavior/04transactionmessage
 * 使用事务消息 https://blog.csdn.net/gsls200808/article/details/133278138
 * @author liuchuang
 * @version 1.0
 * @date 2024/1/30 9:22
 * @modify
 */
@Slf4j
@Component
public class PayOrderNotifyMessageTransactionListener implements TransactionListener {

    @Resource
    private PayOrderMapper payOrderMapper;

    /**
     * 当事务半消息(prepare)发送成功后，此方法将被调用来执行本地事务
     * @param msg Half(prepare) message
     * @param arg Custom business parameter
     * @return Transaction state
     */
    @Override
    public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        log.info("executeLocalTransaction: {}",msg);
        // body为producer发送的message的payload
        log.info("executeLocalTransaction: body={}", new String(msg.getBody()));
        PayOrderNotifyMessage payOrderNotifyMessage = JSONObject.parseObject(new String(msg.getBody()), PayOrderNotifyMessage.class);
        try {
            PayOrderDO orderDO = payOrderMapper.selectByMerchantOrderId(payOrderNotifyMessage.getMerchantOrderId());
            // 订单状态更新为已支付
            if (orderDO.getStatus() == 10){
                return LocalTransactionState.COMMIT_MESSAGE;
            }
            return LocalTransactionState.ROLLBACK_MESSAGE;
        } catch (Exception e){
            return LocalTransactionState.UNKNOW;
        }

    }

    /**
     * When no response to prepare(half) message. broker will send check message to check the transaction status, and this
     * method will be invoked to get local transaction status.
     * 当事务半消息没有响应时，Broker将发送check消息来检查事务状态，并将调用此方法来获取本地事务状态
     *
     * @param msg Check message
     * @return Transaction state
     */
    @Override
    public LocalTransactionState checkLocalTransaction(MessageExt msg) {
        log.info("checkLocalTransaction: {}",msg);
        PayOrderNotifyMessage payOrderNotifyMessage = JSONObject.parseObject(new String(msg.getBody()), PayOrderNotifyMessage.class);
        log.info("checkLocalTransaction payOrderNotifyMessage: {}", JsonUtils.toJsonString(payOrderNotifyMessage));
        try {
            PayOrderDO orderDO = payOrderMapper.selectByMerchantOrderId(payOrderNotifyMessage.getMerchantOrderId());
            // 订单状态更新为已支付
            if (orderDO.getStatus() == 10){
                return LocalTransactionState.COMMIT_MESSAGE;
            }
            return LocalTransactionState.ROLLBACK_MESSAGE;
        } catch (Exception e){
            return LocalTransactionState.UNKNOW;
        }
    }
}
